﻿#include "SysConfigAccess.h"
#include <QDebug>
#include <QUuid>

SysConfigAccess::SysConfigAccess()
{

	m_tableName = "sys_config";
	openDatabase("xiYan");
	createTable(m_tableName);

	this->moveToThread(&m_thread);
	m_thread.start();
}

SysConfigAccess::~SysConfigAccess()
{
	m_thread.quit();
	qDebug() << "~SysConfigAccess";

}

/**
 * @brief 
 * @param name 
 * @return 使用QMetaObject::invokeMethod 带返回值感觉不够优雅应该使用信号根好些
 */
std::optional<xiYan::Result> SysConfigAccess::updateSysConfig(QString name)
{
	QMetaObject::invokeMethod(this, [=]() {
 		QSqlQuery query(m_sqliteDatabase);
		query.prepare(QString("INSERT OR REPLACE INTO %1 (name, value) "
			"VALUES (:name, :value)").arg(m_tableName));
		query.bindValue(":name", name);
		query.bindValue(":value", name);

		if (!query.exec()) {
			//return xiYan::Result(400, query.lastError().text());
		}

		//return xiYan::Result(200,"update successed");;
	});
	return xiYan::Result(200, "update successed");;
}

std::optional<xiYan::Result> SysConfigAccess::openDatabase(const QString& name)
{
	QUuid uuid = QUuid::createUuid();
	QString uuidStr = uuid.toString();

	// 这里目录不存在不会创建 ./Configure/%1/ TODO加判断

	// 数据库名
	QString databaseName = QString("./Configure/%1/configure.db").arg(name);

	// 参数1：数据库驱动 ；参数2：防止冲突
	m_sqliteDatabase = QSqlDatabase::addDatabase("QSQLITE", uuidStr);
	// 设置主机，sqlite不需要，无影响
	m_sqliteDatabase.setHostName("127.0.0.1");
	// 无数据库创建，有数据库打开
	m_sqliteDatabase.setDatabaseName(databaseName);
	// 用户名和密码也不用，无影响
	m_sqliteDatabase.setUserName("");
	m_sqliteDatabase.setPassword("");

	// 防御型编程，有错返回
	if (!m_sqliteDatabase.open())
	{
		QString errMsg = QString("打开失败 %1: %2")
			.arg(databaseName)
			.arg(m_sqliteDatabase.lastError().text());
		return xiYan::Result(400, errMsg);
	}

	return std::nullopt;
}

std::optional<xiYan::Result> SysConfigAccess::createTable(const QString& name)
{

	if (!m_sqliteDatabase.isOpen())	{
		return xiYan::Result(500, "Database is not open");
	}

	QString sql = QString("CREATE TABLE IF NOT EXISTS %1 ("
		"name TEXT PRIMARY KEY NOT NULL,"
		"value TEXT NOT NULL,"
		"last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP)").arg(name);

	QSqlQuery query(m_sqliteDatabase);
	if (!query.exec(sql)) {
		return xiYan::Result(400, query.lastError().text());
	}

	return std::nullopt;
}
